<template>
    <a-layout style="min-height: 100vh">
        <a-layout-sider class="sider" :width="width + 'px'">
            <div class="SiderBox" :style="{ width: width + 'px' }">
                <div class="SelectButton" @click="selectDirectory">选择文件夹</div>
                <div class="InputBox" @keydown.stop="">
                    <a-input v-model:value="FilderName"></a-input>
                </div>
                <div class="FilderBox">
                    <folder :folder="Filder" :level="0" v-if="Filder" />
                </div>
            </div>
        </a-layout-sider>
        <a-layout>
            <Content :Files="files" />
        </a-layout>
    </a-layout>
</template>
<script setup>
import { ref, provide, watch } from 'vue';
import folder from './folder.vue'
import Hotkey from './Hotkey';
import Content from './Content.vue'
import { v4 as uuid } from 'uuid';


const HotkeyEvent = new Hotkey();
const width = ref(400);
const files = ref([]);
const Filder = ref(null);
const SelectId = ref(null);


let FolderArray = [];
let FolderMapping = {};
let FolderCache = [];


let FilterArray = [];
let FilterMapping = {};


const FilderName = ref('');


watch(FilderName, (val) => {
    SelectId.value = null;
    if (val) {
        FilterArray = [];
        FilterMapping = {};
        const _FilterArray = [];
        FolderArray.forEach(item => {
            const folder = FolderMapping[item];
            if (folder.name.indexOf(val) != -1) {
                FilterArray.push(item);
                FilterMapping[item] = folder;
                _FilterArray.push(folder);
            }
        });
        Filder.value.children = _FilterArray;


    } else {
        FilterArray = FolderArray;
        FilterMapping = FolderMapping;
        Filder.value.children = FolderCache;
    }
})


const eachFolder = async function (handle, id) {
    const Filder = [];
    for await (const entry of handle.values()) {
        if (entry.kind == 'directory') {
            const _id = uuid();
            // 获取子目录列表
            const children = await eachFolder(entry, _id);
            // 对子目录按文件名排序，比对去掉数字后的文件夹名称，如果一致，则按照数字大小排序，如果不一致，则按照文件名排序
            const sortedChildren = [...children].sort((a, b) => {
                // 提取去掉所有数字和[]中的内容后的文件名
                const getNameWithoutNumbersAndBrackets = (name) => {
                    // 先去掉[]中的内容
                    const nameWithoutBrackets = name.replace(/\[.*?\]/g, '');
                    // 再去掉所有数字
                    return nameWithoutBrackets.replace(/\d+/g, '');
                };

                // 提取去掉[]后的文件名中的所有数字并连接起来
                const extractAllNumbers = (name) => {
                    // 先去掉[]中的内容
                    const nameWithoutBrackets = name.replace(/\[.*?\]/g, '');
                    // 再提取所有数字
                    const matches = nameWithoutBrackets.match(/\d+/g);
                    return matches ? parseInt(matches.join(''), 10) : NaN;
                };

                const baseNameA = getNameWithoutNumbersAndBrackets(a.name);
                const baseNameB = getNameWithoutNumbersAndBrackets(b.name);
                const numA = extractAllNumbers(a.name);
                const numB = extractAllNumbers(b.name);

                // 先比较去掉数字后的文件名
                if (baseNameA !== baseNameB) {
                    return baseNameA.localeCompare(baseNameB);
                }

                // 如果去掉数字后的文件名一致，则按照数字大小排序
                if (!isNaN(numA) && !isNaN(numB)) {
                    return numA - numB;
                } else if (!isNaN(numA)) {
                    return -1; // 有数字的排在前面
                } else if (!isNaN(numB)) {
                    return 1;  // 有数字的排在前面
                } else {
                    return a.name.localeCompare(b.name, "zh-Hans-CN");
                    // 都没有数字，按原文件名排序
                }
            });
            const Obj = {
                name: entry.name,
                id: _id,
                kind: entry.kind,
                parent: id,
                handle: entry,
                children: sortedChildren
            }
            FolderMapping[_id] = Obj;
            Filder.push(Obj);
        };
    };
    return Filder
}



const GetFilterContent = async function (handle, id) {
    SelectId.value = id;
    files.value = [];
    const _file = [];
    for await (const entry of handle.values()) {
        if (entry.kind != 'directory') {
            const file = await entry.getFile();
            if (file.type.indexOf('image/') != -1) {
                _file.push(file)
            };
        };
    };
    files.value = _file;
};
provide('SelectId', SelectId);
provide('GetFilterContent', GetFilterContent)

async function selectDirectory() {
    const handle = await window.showDirectoryPicker();
    Filder.value = { name: handle.name, kind: handle.kind, id: uuid(), parent: null, handle: handle, children: [] }
    Filder.value.children = await eachFolder(handle);
    FolderArray = [];

    // 递归函数，将文件夹的id按顺序添加到FolderArray中
    const addIdsToFolderArray = (children) => {
        if (!children) return;
        for (const child of children) {
            FolderArray.push(child.id);
            addIdsToFolderArray(child.children);
        }
    };

    addIdsToFolderArray(Filder.value.children);
    FolderCache = Filder.value.children;
    FilterArray = FolderArray;
    FilterMapping = FolderMapping;
}

HotkeyEvent.addHotkey('[', function () {
    console.log('Pro');
    let index = FilterArray.indexOf(SelectId.value);
    if (index == -1) {
        index = 0
    } else {
        index--
    };
    if (index != 0) {
        SelectId.value = FilterArray[index];
        GetFilterContent(FilterMapping[SelectId.value].handle, SelectId.value);
    }
})
HotkeyEvent.addHotkey(']', function () {
    let index = FilterArray.indexOf(SelectId.value);
    if (index == -1) {
        index = 0
    } else {
        index++
    };
    if (index != FilterArray.length - 1) {
        SelectId.value = FilterArray[index];
        GetFilterContent(FilterMapping[SelectId.value].handle, SelectId.value);
    }
})


</script>
<style scoped lang="less">
.InputBox {
    padding-top: 4px;
}

.FilderBox {
    position: absolute;
    top: 80px;
    bottom: 0;
    width: 100%;
    overflow-y: auto;
}

.SelectButton {
    height: 40px;
    line-height: 40px;
    padding: 0 12px;
    border-bottom: 1px solid #666;
    cursor: pointer;
    transition: all 0.2s;

    &:hover {
        background-color: rgba(200, 200, 200, 0.4);
    }
}

.sider {
    color: #fff;

}

.SiderBox {
    position: fixed;
    height: 100%;
    user-select: none;
}

#components-layout-demo-side .logo {
    height: 32px;
    margin: 16px;
    background: rgba(255, 255, 255, 0.3);
}

.site-layout .site-layout-background {
    background: #fff;
}

[data-theme='dark'] .site-layout .site-layout-background {
    background: #141414;
}
</style>